// MemStream.h: interface for the CMemStream class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_MEMSTREAM_H__5B10BD9A_11B2_4DB1_AD19_311A234B1781__INCLUDED_)
#define AFX_MEMSTREAM_H__5B10BD9A_11B2_4DB1_AD19_311A234B1781__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include <oleauto.h>

namespace algotools
{
	
	/*! \brief HGLOBAL Handler 

	*/
	class CHGlobalWrapper
	{
	private:
		CHGlobalWrapper( const CHGlobalWrapper&);
		CHGlobalWrapper& operator=( const CHGlobalWrapper&);
	public:
		//! Constructor
		CHGlobalWrapper();
		
		//! destructor
		virtual ~CHGlobalWrapper();

		//! returns true if object is valid
		virtual bool IsValid() const	{	return m_hGlobal != NULL;};

		//! Gets underlying HGlobal
		HGLOBAL ToHandle()				{	 return m_hGlobal;};

		//! lock to LPVOID
		LPVOID LockToLPVOID();
		//! Unlock handle
		void UnLock();

		//! returns a copy of the handle
		SAFEARRAY* ToSafeArray();

		//! return a vairant copy of the handle
		const VARIANT& ToVariant();
		
		//! returns size of handle in bytes
		size_t Size() const				{	return static_cast<size_t>(::GlobalSize(m_hGlobal));};
		
	private:
		//! locks handle
		LPVOID Lock();

		//! Clear handle
		void ClearHandle();		
		//! Clear safe array
		void ClearSafeArray();		
		//! updates
		void UpdateSafeArray();
	private:
		//! locked state
		bool m_bLocked;
		//! safe array flag
		bool m_bSAUpdated;
		//! global handle
		HGLOBAL m_hGlobal;
		//! Safe Array
		SAFEARRAY* m_pSafeArray;
		//! Varaint
		VARIANT m_var;
	};
		

	/*! \brief IStream handler
	
	*/
	class CMemStream : public CHGlobalWrapper
	{
	private:
		CMemStream(const CMemStream&);
		CMemStream& operator=(const CMemStream&);
	public:
		//! Default constructor
		CMemStream( );
		//! Destructor
		virtual ~CMemStream()			{	ClearStream(); };
	
		//! returns true if valid
		virtual bool IsValid() const	{	return CHGlobalWrapper::IsValid() && !FAILED(m_hResult);};

		//! Returns stream
		IStream* ToStream()				{	return m_pStream;}; 		
	protected:
		//! Clearing strem
		void ClearStream();
	private:
		//! hresult
		HRESULT m_hResult;
		//! Stream
		IStream* m_pStream;

	};

};
#endif // !defined(AFX_MEMSTREAM_H__5B10BD9A_11B2_4DB1_AD19_311A234B1781__INCLUDED_)
